﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Reflection;
using System.Web.UI.WebControls;
using System.Web.UI;
using Menu = Microsoft.SharePoint.WebControls.Menu;
using System.Globalization;

namespace DevSky.SharePoint.Core.Controls
{
  public enum MENUACTION : byte
  {
    UNDEFINED = 0,
    SELECTION = 1,
    NEW = 2,
    DELETE = 3
  }

  public class MenuSelectionEventArgs : EventArgs
  {
    private string param = string.Empty;
    public MenuSelectionEventArgs(string param) : base()
    {
      this.param = param;
    }
  }
  public class SPGridViewAdvanced : SPGridView
  {    
    public event EventHandler<MenuSelectionEventArgs> MenuSelection;
    public event EventHandler<MenuSelectionEventArgs> MenuDelete;

    private string selectedMenuValue = string.Empty;
    private MENUACTION selectedAction = MENUACTION.UNDEFINED;

    // HACK: http://www.reversealchemy.net/blog/2010/02/01/building-a-spgridview-control-%E2%80%93-part-4-filtering-multiple-columns/
    // HACK: http://it666.blogspot.com/2008/06/spgridview-filtering.html
    // HACK: http://social.msdn.microsoft.com/Forums/en/sharepointdevelopment/thread/f533f4e8-cf66-484f-8803-282445002dd0
    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
      if (this.HeaderRow != null)
      {
        foreach (TableCell cell in this.HeaderRow.Cells)
        {
          if (cell.Controls.Count > 0)
          {
            Menu menu = (cell.Controls[0] as Menu);
            if (menu != null)
            {
                cell.Style["vertical-align"] = "middle";                
                cell.Style["border-top-width"] = "1px";
                cell.Style["border-right-width"] = "1px";
                cell.Style["padding-top"] = "0px";
                menu.ClientOnClickPreMenuOpen = menu.ClientOnClickPreMenuOpen.Replace("%TEMPLATECLIENTID%", ClientID + "_SPGridViewFilterMenuTemplate");                
            }
          }
        }
      }
      try
      {
          base.Render(writer);
      }
      catch (Exception)
      {
      }
    }

    // Hack: Ansonsten wird das Filter Icon nicht angezeigt
    protected override void OnRowDataBound(System.Web.UI.WebControls.GridViewRowEventArgs e)
    {
        base.OnRowDataBound(e);
      if (e.Row.RowType != DataControlRowType.Header)
        return;
      if (String.IsNullOrEmpty(FilterFieldName) && String.IsNullOrEmpty(SortExpression))
        return;
      DataControlField field = null;
      for (int i = 0; i < Columns.Count; i++)
      {
        field = Columns[i];
        if (field.SortExpression != null && field.SortExpression.Length > 0)
        {          
          if (field.HeaderText == FilterFieldName)
          {
            Image filterIcon = new Image();
            filterIcon.ImageUrl = "/_layouts/images/filter.gif";
            filterIcon.Style[HtmlTextWriterStyle.MarginLeft] = "2px";
            Literal headerText = new Literal();
            headerText.Text = field.HeaderText;
            PlaceHolder panel = new PlaceHolder();
            panel.Controls.Add(headerText);
            panel.Controls.Add(filterIcon);
            e.Row.Cells[i].Controls.Clear();
            e.Row.Cells[i].Controls.Add(panel);
          }
        }
      }      
    }
   
    //http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/c3c8aef9-bff6-46bc-a87c-de0a764fb31c
    //http://sadomovalex.blogspot.com/2011/03/spgridview-with-filtering-by-multiple.html
    //http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/03/30/building-a-better-spgridview.aspx

    //http://johanleino.wordpress.com/2009/05/12/solving-using-the-clientonclickusingpostbackevent-in-ascx-usercontrols/
    //http://blog.avanadeadvisor.com/blogs/johanr/default.aspx
    //http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.menuitemtemplate.clientonclickpostbackconfirmation.aspx#Y184


    //http://ochoco.blogspot.com/2009/03/how-to-work-around-bugs-in-spgridview.html
    protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
    {
      FieldInfo fieldInfo = typeof(SPGridView).GetField("previousGroupFieldValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 
      if (fieldInfo != null) 
        fieldInfo.SetValue(this, null);
      int returnValue = -1;
      try
      {
          returnValue = base.CreateChildControls(dataSource, dataBinding);
      }
      catch (Exception)
      {
      }       
      if (this.AllowFiltering && this.HeaderRow != null && !string.IsNullOrEmpty(this.SortExpression))            
      {                
        List<string> filterFields = new List<string>(this.FilterDataFields.Split(','));                
        if (this.AllowGrouping) 
            filterFields.Insert(0, string.Empty);                
        for (int i = 0; i < this.HeaderRow.Cells.Count; i++)                
        {                    
          DataControlFieldHeaderCell cell = this.HeaderRow.Cells[i] as DataControlFieldHeaderCell;                    
          if (cell != null)                    
          {                        
            // Find the sort image control                       
            Image sortImage = null;                        
            foreach (Control c in cell.Controls)                        
            {                            
              sortImage = c as Image;                            
              if (sortImage != null && sortImage.ImageUrl == this.SortDirectionImageUrl)                               
                break;                        
            }
            if (i < filterFields.Count && filterFields[i].Trim() != string.Empty)                        
            {                            
              // If there is also an image control, remove it (we'll add it back in the right place)                            
              if (sortImage != null) 
                  cell.Controls.Remove(sortImage);                            
              // Find the menu control and add or remove the image in there as needed                            
              foreach (Control c in cell.Controls)                            
              {                                
                if (c is Microsoft.SharePoint.WebControls.Menu)                                
                {                                    
                  Microsoft.SharePoint.WebControls.Menu menu = c as Microsoft.SharePoint.WebControls.Menu;                                   
                  if (this.SortExpression.Equals(this.Columns[i].SortExpression, StringComparison.InvariantCultureIgnoreCase))                                    
                  {                                        
                    // Make sure it has the sort indicator                                        
                    menu.RightImageUrl = this.SortDirectionImageUrl;                                        
                    menu.ImageTextSpacing = new Unit("2px", CultureInfo.InvariantCulture);                                    
                  }
                  else if (menu.RightImageUrl == this.SortDirectionImageUrl)                                    
                  {                                        
                    // Make sure it doesn't have the sort indicator                                        
                    menu.RightImageUrl = null;                                        
                    menu.ImageTextSpacing = Unit.Empty;                                    
                  }                                
                }                            
              }                        
            }                        
            else                        
            {
              if (this.SortExpression.Equals(this.Columns[i].SortExpression, StringComparison.InvariantCultureIgnoreCase))                            
              {                                
                // Make sure there is a sort image                                
                if (sortImage == null)                                
                {                                    
                  sortImage = new Image();                                    
                  sortImage.ImageUrl = this.SortDirectionImageUrl;                                    
                  sortImage.Style[HtmlTextWriterStyle.MarginLeft] = "2px";                                    
                  cell.Controls.Add(sortImage);                                
                }                            
              }                            
              else if (sortImage != null)                            
              {                                
                // Remove the sort image if it exists                                
                cell.Controls.Remove(sortImage);                            
              }                        
            }                    
          }                
        }            
      }            
      return returnValue;
    }

    //protected override void RaisePostBackEvent(string eventArgument)
    //{
    //    base.RaisePostBackEvent(eventArgument);
    //    selectedAction = MENUACTION.UNDEFINED;
    //    if ((!string.IsNullOrEmpty(eventArgument)) && eventArgument.StartsWith("ID:"))
    //    {
    //        selectedAction = MENUACTION.SELECTION;
    //        selectedMenuValue = eventArgument.Split(new char[] { ':' })[1].ToString();
    //        OnMenuSelection(new MenuSelectionEventArgs(eventArgument));
    //    }
    //    if ((!string.IsNullOrEmpty(eventArgument)) && eventArgument.StartsWith("DELETE:"))
    //    {
    //        selectedMenuValue = eventArgument.Split(new char[] { ':' })[1].ToString();
    //        selectedAction = MENUACTION.DELETE;
    //        OnMenuDelete(new MenuSelectionEventArgs(eventArgument));
    //    }
    //}

    protected virtual void OnMenuSelection(MenuSelectionEventArgs e)
    {
      if (MenuSelection != null)
      {
        MenuSelection(this, e);
      }
    }

    protected virtual void OnMenuDelete(MenuSelectionEventArgs e)
    {
      if (MenuDelete != null)
      {
        MenuDelete(this, e);
      }
    }

    public string SelectedKey
    {
      get
      {
        return selectedMenuValue;
      }
    }

    public MENUACTION SelectedAction
    {
      get
      {
        return selectedAction;
      }
    }
  }
}
